#ifndef V2_NIM_FRIEND_SERVICE_H
#define V2_NIM_FRIEND_SERVICE_H
#include "v2_nim_internal.hpp"
namespace v2 {
/// @brief 好友服务
/// @pre
/// 调用 `V2NIMClient::get()` 拿到 client 实例
/// 调用 `client.getFriendService()` 拿到 friendService 实例
/// @par 示例代码
/// @code
/// auto& client = V2NIMClient::get();
/// auto& friendService = client.getFriendService();
/// @endcode
class V2NIMFriendService {
public:
    /// @brief 添加好友
    /// @param accountId 账号 ID
    /// @param params 添加好友参数
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendAddParams params;
    /// params.addMode = V2NIM_FRIEND_MODE_TYPE_ADD;
    /// params.postscript = "hello";
    /// friendService.addFriend(
    ///     "account",
    ///     params,
    ///     []() {
    ///         // add friend success
    ///     },
    ///     [](V2NIMError error) {
    ///         // add friend failed, handle error
    ///     });
    /// @endcode
    virtual void addFriend(nstd::string accountId, V2NIMFriendAddParams params, V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 删除好友
    /// @param accountId 账号 ID
    /// @param params 删除好友参数
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendDeleteParams params;
    /// params.deleteAlias = true;
    /// friendService.deleteFriend(
    ///     "account",
    ///     params,
    ///     []() {
    ///         // delete friend success
    ///     },
    ///     [](V2NIMError error) {
    ///         // delete friend failed, handle error
    ///     });
    /// @endcode
    virtual void deleteFriend(nstd::string accountId,
        V2NIMFriendDeleteParams params,
        V2NIMSuccessCallback<void> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 接受好友申请，调用该 API 后该申请的状态会变为已同意，同时标记为已读
    /// @param application 好友申请
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendAddApplication application;
    /// // get application from listener or query
    /// // ...
    /// friendService.acceptAddApplication(
    ///     application,
    ///     []() {
    ///         // accept friend request success
    ///     },
    ///     [](V2NIMError error) {
    ///         // accept friend request failed, handle error
    ///     });
    /// @endcode
    virtual void acceptAddApplication(V2NIMFriendAddApplication application, V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 拒绝好友申请，在调用此 API 后该申请的状态会变为已拒绝，同时标记为已读
    /// @param application 好友申请
    /// @param postscript 附言
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendAddApplication application;
    /// // get application from listener or query
    /// // ...
    /// friendService.rejectAddApplication(
    ///     application,
    ///     "postscript",
    ///     []() {
    ///         // reject friend request success
    ///     },
    ///     [](V2NIMError error) {
    ///         // reject friend request failed, handle error
    ///     });
    /// @endcode
    virtual void rejectAddApplication(V2NIMFriendAddApplication application,
        nstd::string postscript,
        V2NIMSuccessCallback<void> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 设置好友信息
    /// @param accountId 账号 ID
    /// @param params 设置好友信息参数
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendSetParams params;
    /// params.alias = "alias";
    /// friendService.setFriendInfo(
    ///     "account",
    ///     params,
    ///     []() {
    ///         // set friend info success
    ///     },
    ///     [](V2NIMError error) {
    ///         // set friend info failed, handle error
    ///     });
    /// @endcode
    virtual void setFriendInfo(nstd::string accountId,
        V2NIMFriendSetParams params,
        V2NIMSuccessCallback<void> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 获取好友列表
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// friendService.getFriendList(
    ///     [](nstd::vector<V2NIMFriend> friends) {
    ///         // get friend list success, handle friends
    ///     },
    ///     [](V2NIMError error) {
    ///         // get friend list failed, handle error
    ///     });
    /// @endcode
    virtual void getFriendList(V2NIMSuccessCallback<nstd::vector<V2NIMFriend>> success, V2NIMFailureCallback failure) = 0;

    /// @brief 根据账号 ID 获取好友信息
    /// @param accountIds 账号 ID 列表
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// friendService.getFriendByIds(
    ///     {"account1", "account2"},
    ///     [](nstd::vector<V2NIMFriend> friends) {
    ///         // get friend list success, handle friends
    ///     },
    ///     [](V2NIMError error) {
    ///         // get friend list failed, handle error
    ///     });
    /// @endcode
    virtual void getFriendByIds(nstd::vector<nstd::string> accountIds,
        V2NIMSuccessCallback<nstd::vector<V2NIMFriend>> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 根据账号 ID 检查好友状态
    /// @param accountIds 账号 ID 列表
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// friendService.checkFriend(
    ///     {"account1", "account2"},
    ///     [](nstd::map<nstd::string, bool> checkList) {
    ///         // check friend success, handle checkList
    ///     },
    ///     [](V2NIMError error) {
    ///         // check friend failed, handle error
    ///     });
    /// @endcode
    virtual void checkFriend(nstd::vector<nstd::string> accountIds,
        V2NIMSuccessCallback<nstd::map<nstd::string, bool>> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 获取申请添加好友信息列表
    /// @param option 查询申请添加好友相关信息参数
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendAddApplicationQueryOption option;
    /// option.offset = 0;
    /// option.limit = 10;
    /// friendService.getAddApplicationList(
    ///     option,
    ///     [](V2NIMFriendAddApplicationResult result) {
    ///         // query add application list success, handle result
    ///     },
    ///     [](V2NIMError error) {
    ///         // query add application list failed, handle error
    ///     });
    /// @endcode
    virtual void getAddApplicationList(V2NIMFriendAddApplicationQueryOption option,
        V2NIMSuccessCallback<V2NIMFriendAddApplicationResult> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 获取申请添加好友未读数
    /// 统计所有状态为未处理，且未读的数量
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// friendService.getAddApplicationUnreadCount(
    ///    [](uint32_t count) {
    ///        // get add application unread count success, handle count
    ///    },
    ///    [](V2NIMError error) {
    ///        // get add application unread count failed, handle error
    ///    });
    /// @endcode
    virtual void getAddApplicationUnreadCount(V2NIMSuccessCallback<uint32_t> success, V2NIMFailureCallback failure) = 0;

    /// @brief 设置好友申请已读
    /// 调用该方法，历史数据未读数据均标记为已读
    /// @param success 成功回调
    /// @param failure 失败回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// friendService.setAddApplicationRead(
    ///     []() {
    ///         // set add application read success
    ///     },
    ///     [](V2NIMError error) {
    ///         // set add application read failed, handle error
    ///     });
    /// @endcode
    virtual void setAddApplicationRead(V2NIMSuccessCallback<void> success, V2NIMFailureCallback failure) = 0;

    /// @brief 根据关键字搜索好友信息
    /// @param option 好友搜索相关参数
    /// @param success 搜索成功的回调
    /// @param failure 搜索失败的回调
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendSearchOption option;
    /// option.keyword = "keyword";
    /// friendService.searchFriendByOption(
    ///    option,
    ///    [](nstd::vector<V2NIMFriend> friends) {
    ///    // search friend success, handle friends
    ///    },
    ///    [](V2NIMError error) {
    ///    // search friend failed, handle error
    ///    });
    /// @endcode
    virtual void searchFriendByOption(const V2NIMFriendSearchOption& option,
        V2NIMSuccessCallback<nstd::vector<V2NIMFriend>> success,
        V2NIMFailureCallback failure) = 0;

    /// @brief 添加好友监听器
    /// @param listener 监听器
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendListener listener;
    /// listener.onSyncStarted = []() {
    ///     // sync friend started
    /// };
    /// listener.onSyncFinished = []() {
    ///     // sync friend finished
    /// };
    /// listener.onSyncFailed = [](V2NIMError error) {
    ///     // sync friend failed, handle error
    /// };
    /// listener.onFriendAdded = [](V2NIMFriend friendInfo) {
    ///     // friend added, handle friendInfo
    /// };
    /// listener.onFriendDeleted = [](nstd::string accountId, V2NIMFriendDeletionType deletionType) {
    ///     // friend deleted
    /// };
    /// listener.onFriendAddApplication = [](V2NIMFriendAddApplication applicationInfo) {
    ///     // friend add application, handle applicationInfo
    /// };
    /// listener.onFriendAddRejected = [](V2NIMFriendAddRejection rejectionInfo) {
    ///     // friend add rejected, handle rejectionInfo
    /// };
    /// listener.onFriendInfoChanged = [](V2NIMFriend friendInfo) {
    ///     // friend info changed, handle friendInfo
    /// };
    /// friendService.addFriendListener(listener);
    /// @endcode
    virtual void addFriendListener(V2NIMFriendListener listener) = 0;

    /// @brief 移除好友监听器
    /// @param listener 监听器
    /// @return void
    /// @par 示例代码
    /// @code
    /// V2NIMFriendListener listener;
    /// // ...
    /// friendService.addFriendListener(listener);
    /// // ...
    /// friendService.removeFriendListener(listener);
    /// @endcode
    virtual void removeFriendListener(V2NIMFriendListener listener) = 0;
};
}  // namespace v2
#endif
